package tbs.framework.sql.provider;

import lombok.val;
import tbs.framework.interfaces.IChainProvider;
import tbs.framework.interfaces.impls.chain.AbstractChain;
import tbs.framework.sql.converter.AbstractConvertor;
import tbs.framework.utils.ChainUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 抽象转换链提供器
 *
 * @author abstergo
 */
public abstract class AbstractConvertChainProvider implements IChainProvider<Object, String> {

    private static Map<Class, Boolean> supportMap = new HashMap<>();

    private boolean isSupport(Object c) {
        return supportMap.computeIfAbsent(c != null ? c.getClass() : Void.class, k -> {
            for (AbstractConvertor convertor : getConvertors()) {
                if (convertor.support(c)) {
                    return true;
                }
            }
            return false;
        });
    }

    /**
     * 所有的转换器
     *
     * @return
     */
    protected abstract List<AbstractConvertor> getConvertors();

    @Override
    public AbstractChain<Object, String> beginChain() {

        AbstractChain.Builder builder = new AbstractChain.Builder();

        for (AbstractConvertor convertor : getConvertors()) {
            builder.add(convertor);
        }
        return builder.build();
    }

    public static final String process(AbstractConvertChainProvider chainProvider, Object val) {
        if (!chainProvider.isSupport(val)) {
            throw new RuntimeException("不支持的转换类型:" + val.getClass().getName());
        }
        return ChainUtil.process(chainProvider.beginChain(), val).toString();
    }
}
